use super::{err, err_value, ECode, Resp};
use serde_json::Value;
use std::fs;
use tracing::{instrument, warn};

pub struct JsonFile;

impl JsonFile {
    pub fn is_exist(path: &str) -> Result<bool, Value> {
        let is_exist = fs::exists(path).or_else(|e| err!(ECode::FileDel, e))?;
        Ok(is_exist)
    }

    #[instrument(skip_all, name = "del_file")]
    pub fn del_file(path: &str) -> Result<(), Value> {
        let is_exist = fs::exists(path).or_else(|e| err!(ECode::FileDel, e))?;

        if !is_exist {
            return Ok(());
        }

        fs::remove_file(path).or_else(|e| {
            warn!("rm file error, {path}: {:?}", e);
            err!(ECode::FileDel, e)
        })?;

        Ok(())
    }

    #[instrument(skip_all, name = "read_file")]
    pub fn read_file(path: &str) -> Resp {
        let contents = fs::read_to_string(&path).or_else(|e| {
            warn!("read file error, {path}: {:?}", e);
            err!(ECode::FileRead, e)
        })?;

        serde_json::from_str(&contents).or_else(|e| {
            warn!("read file error, {path}: {:?}", e);
            err!(ECode::FileRead, e)
        })
    }

    #[instrument(skip_all, name = "write_file")]
    pub fn write_file(path: &str, data: &Value) -> Result<(), Value> {
        fs::write(&path, data.to_string()).or_else(|e| {
            warn!("write file error, {path}: {:?}", e);
            err!(ECode::FileWrite, e)
        })?;

        Ok(())
    }

    #[instrument(skip_all, name = "make_dir")]
    pub fn make_dir(path: &str) -> Result<(), Value> {
        fs::create_dir_all(path).or_else(|e| {
            warn!("make dir error, {path}: {:?}", e);
            err!(ECode::DirMake, e)
        })?;

        Ok(())
    }
}
